#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'ethereal'
__mtime__ = '2018/9/1'
# -*- coding: utf-8 -*-
import hashlib,time,random,decimal,json
from application import  app,db
from common.models.food.Food import Food
from common.models.food.FoodSaleChangeLog import FoodSaleChangeLog
from common.models.pay.PayOrder import PayOrder
from common.models.pay.PayOrderItem import PayOrderItem
from common.models.pay.PayOrderCallbackData import PayOrderCallbackData
from common.libs.Helper import getCurrentDate
# from common.libs.queue.QueueService import QueueService
from common.libs.food.FoodService import FoodService


class PayService():

    def __init__(self):
        pass

    #创建订单
    def createOrder(self,member_id,items = None,params = None):
        resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
        pay_price  = decimal.Decimal( 0.00 )#付款价格转换
        continue_cnt = 0
        food_ids = []
        for item in items:
            if decimal.Decimal( item['price'] ) < 0 :
                continue_cnt += 1
                continue

            pay_price = pay_price +  decimal.Decimal( item['price'] ) * int( item['number'] )
            food_ids.append( item['id'] )

        if continue_cnt >= len(items ) :
            resp['code'] = -1
            resp['msg'] = '商品items为空~~'
            return resp
         #运费判断
        yun_price = params['yun_price'] if params and 'yun_price' in params else 0
        note = params['note'] if params and 'note' in params else ''
        express_address_id = params['express_address_id'] if params and 'express_address_id' in params else 0
        express_info = params['express_info'] if params and 'express_info' in params else {}
        yun_price = decimal.Decimal( yun_price )
        total_price = pay_price + yun_price#总和
        try:
            #悲观锁 锁住  防止更改 多个查询一定会排队
            #为了防止并发库存出问题了，我们坐下selectfor update, 这里可以给大家演示下
            tmp_food_list = db.session.query( Food ).filter( Food.id.in_( food_ids ) )\
                .with_for_update().all()#行级别锁

            tmp_food_stock_mapping = {}
            for tmp_item in tmp_food_list:
                tmp_food_stock_mapping[ tmp_item.id ] = tmp_item.stock
            #主表生成数据
            model_pay_order = PayOrder()
            model_pay_order.order_sn = self.geneOrderSn()#生成唯一
            model_pay_order.member_id = member_id
            model_pay_order.total_price = total_price
            model_pay_order.yun_price = yun_price
            model_pay_order.pay_price = pay_price
            model_pay_order.note = note
            model_pay_order.status = -8 #代付款状态
            model_pay_order.express_status = -8  #代支付状态
            model_pay_order.express_address_id = express_address_id
            model_pay_order.express_info = json.dumps(  express_info )
            model_pay_order.updated_time = model_pay_order.created_time = getCurrentDate()
            db.session.add( model_pay_order )
            #db.session.flush()
            for item in items:
                tmp_left_stock =  tmp_food_stock_mapping[ item['id'] ]

                if decimal.Decimal(item['price']) < 0:
                    continue

                if int( item['number'] ) > int( tmp_left_stock ):
                    raise Exception( "您购买的这美食太火爆了，剩余：%s,你购买%s~~"%( tmp_left_stock,item['number'] ) )
                #更新库存
                tmp_ret = Food.query.filter_by( id = item['id'] ).update({
                    "stock":int(tmp_left_stock) - int(item['number'])
                })
                if not tmp_ret:
                    raise Exception("下单失败请重新下单")
                #从表写入数据
                tmp_pay_item = PayOrderItem()
                tmp_pay_item.pay_order_id = model_pay_order.id
                tmp_pay_item.member_id = member_id
                tmp_pay_item.quantity = item['number']
                tmp_pay_item.price = item['price']
                tmp_pay_item.food_id = item['id']
                tmp_pay_item.note = note
                tmp_pay_item.updated_time = tmp_pay_item.created_time = getCurrentDate()
                db.session.add( tmp_pay_item )
                #db.session.flush()

                FoodService.setStockChangeLog( item['id'],-item['number'],"在线购买" )
            db.session.commit()
            #成功之后的数据返回
            resp['data'] = {
                'id' : model_pay_order.id,
                'order_sn' : model_pay_order.order_sn,
                'total_price':str( total_price )
            }
        except Exception as e:
            db.session.rollback()#回滚
            print( e )
            resp['code'] = -1
            resp['msg'] = "下单失败请重新下单"
            resp['msg'] = str(e)
            return resp
        return resp

    def closeOrder(self,pay_order_id = 0):
        if pay_order_id < 1:
            return False
        pay_order_info = PayOrder.query.filter_by( id =  pay_order_id ,status = -8 ).first()
        if not pay_order_info:
            return False

        pay_order_items = PayOrderItem.query.filter_by( pay_order_id = pay_order_id ).all()
        if pay_order_items:
            #需要归还库存
            for item in pay_order_items:
                tmp_food_info = Food.query.filter_by( id = item.food_id ).first()
                if tmp_food_info:
                    tmp_food_info.stock = tmp_food_info.stock + item.quantity
                    tmp_food_info.updated_time = getCurrentDate()
                    db.session.add( tmp_food_info )
                    db.session.commit()
                    FoodService.setStockChangeLog( item.food_id, item.quantity, "订单取消")

        pay_order_info.status = 0
        pay_order_info.updated_time = getCurrentDate()
        db.session.add( pay_order_info )
        db.session.commit()
        return True

    def orderSuccess(self,pay_order_id = 0,params = None):
        try:
            pay_order_info = PayOrder.query.filter_by( id = pay_order_id ).first()
            if not pay_order_info or pay_order_info.status not in [ -8,-7 ]:
                return True

            pay_order_info.pay_sn = params['pay_sn'] if params and 'pay_sn' in params else ''
            pay_order_info.status = 1
            pay_order_info.express_status = -7
            pay_order_info.updated_time = getCurrentDate()
            db.session.add( pay_order_info  )


            pay_order_items = PayOrderItem.query.filter_by( pay_order_id = pay_order_id ).all()
            for order_item in pay_order_items:
                tmp_model_sale_log = FoodSaleChangeLog()
                tmp_model_sale_log.food_id = order_item.food_id
                tmp_model_sale_log.quantity = order_item.quantity
                tmp_model_sale_log.price = order_item.price
                tmp_model_sale_log.member_id = order_item.member_id
                tmp_model_sale_log.created_time = getCurrentDate()
                db.session.add( tmp_model_sale_log )

            db.session.commit()
        except Exception as e:
            db.session.rollback()
            print(e)
            return False

        #加入通知队列，做消息提醒和
        # QueueService.addQueue( "pay",{
        #     "member_id": pay_order_info.member_id,
        #     "pay_order_id":pay_order_info.id
        # })
        return True

    def addPayCallbackData(self,pay_order_id = 0,type = 'pay',data = ''):
        model_callback = PayOrderCallbackData()
        model_callback.pay_order_id = pay_order_id
        if type == "pay":
            model_callback.pay_data = data
            model_callback.refund_data = ''
        else:
            model_callback.refund_data = data
            model_callback.pay_data = ''

        model_callback.created_time = model_callback.updated_time = getCurrentDate()
        db.session.add( model_callback )
        db.session.commit()
        return True

    def geneOrderSn(self):
        m = hashlib.md5()
        sn = None
        while True:
            str = "%s-%s"%( int( round( time.time() * 1000) ),random.randint( 0,9999999 ) )
            m.update(str.encode("utf-8"))
            sn = m.hexdigest()
            if not PayOrder.query.filter_by( order_sn = sn  ).first():
                break
        return sn

